#include <microhttpd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <cJSON.h>

#define PORT 3001

struct connection_info {
    char *buffer;
    size_t size;
};

static int handle_hello_request(const char **response_data) {
    cJSON *hello_json = cJSON_CreateObject();
    cJSON_AddStringToObject(hello_json, "message", "Hello from C API!");
    *response_data = cJSON_Print(hello_json);
    cJSON_Delete(hello_json);
    return MHD_HTTP_OK;
}

static int handle_login_request(struct connection_info *con_info, 
                              const char **response_data, 
                              int *status_code) {
    // 检查是否有POST数据
    if (con_info->buffer == NULL) {
        *response_data = "{ \"success\": false, \"message\": \"No JSON data received\" }";
        *status_code = MHD_HTTP_BAD_REQUEST;
        return 0;
    }

    // 解析JSON请求体
    printf("Received JSON data: %s\n", con_info->buffer);
    cJSON *root = cJSON_Parse(con_info->buffer);
    
    if (!root) {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr) {
            printf("JSON parse error at: %s\n", error_ptr);
        }
        *response_data = "{ \"success\": false, \"message\": \"Invalid JSON format - keys must be quoted\" }";
        *status_code = MHD_HTTP_BAD_REQUEST;
        return 0;
    }

    // 提取用户名和密码
    cJSON *username_json = cJSON_GetObjectItemCaseSensitive(root, "username");
    cJSON *password_json = cJSON_GetObjectItemCaseSensitive(root, "password");
    
    const char *username = cJSON_GetStringValue(username_json);
    const char *password = cJSON_GetStringValue(password_json);
    
    if (username && password && strcmp(username, "admin") == 0 && strcmp(password, "123456") == 0) {
        *response_data = "{ \"success\": true, \"token\": \"dummy_token\", \"message\": \"Login successful\" }";
    } else {
        *response_data = "{ \"success\": false, \"message\": \"Invalid username or password\" }";
        *status_code = MHD_HTTP_UNAUTHORIZED;
    }
    
    cJSON_Delete(root);
    return 1;
}

static int check_content_type(struct MHD_Connection *connection,
                            const char **response_data,
                            int *status_code) {
    const char *content_type = MHD_lookup_connection_value(connection, 
                                                          MHD_HEADER_KIND, 
                                                          "Content-Type");
    if (!content_type || strstr(content_type, "application/json") == NULL) {
        *response_data = "{ \"success\": false, \"message\": \"Invalid Content-Type, expected application/json\" }";
        *status_code = MHD_HTTP_BAD_REQUEST;
        return 0;
    }
    return 1;
}

static int handle_request(void *cls, struct MHD_Connection *connection,
                         const char *url, const char *method,
                         const char *version, const char *upload_data,
                         size_t *upload_data_size, void **con_cls) {
    
    const char *response_data = NULL;
    int status_code = MHD_HTTP_OK;
    struct connection_info *con_info = *con_cls;

    // 初始化连接信息
    if (con_info == NULL) {
        con_info = malloc(sizeof(struct connection_info));
        if (con_info == NULL) {
            return MHD_NO;
        }
        con_info->buffer = NULL;
        con_info->size = 0;
        *con_cls = con_info;
    }

    // 处理POST数据
    printf("Request method: %s, URL: %s\n", method, url);
    if (strcmp(method, "POST") == 0) {
        const char *content_length = MHD_lookup_connection_value(connection, 
                                                               MHD_HEADER_KIND, 
                                                               "Content-Length");
        printf("Content-Length: %s\n", content_length ? content_length : "NULL");
        
        // 初始化连接后立即返回MHD_YES以等待数据
        if (con_info->buffer == NULL && *upload_data_size == 0) {
            return MHD_YES;
        }
    
        if (*upload_data_size != 0) {
            printf("Receiving POST data, size: %zu\n", *upload_data_size);
            char *ptr = realloc(con_info->buffer, con_info->size + *upload_data_size + 1);
            if (ptr == NULL) {
                return MHD_NO;
            }
            con_info->buffer = ptr;
            memcpy(con_info->buffer + con_info->size, upload_data, *upload_data_size);
            con_info->size += *upload_data_size;
            con_info->buffer[con_info->size] = '\0';
            printf("Current buffer content: %s\n", con_info->buffer);
            *upload_data_size = 0;
            return MHD_YES;
        } else if (*con_cls != NULL) {
            printf("No POST data received (upload_data: %p, upload_data_size: %zu)\n", 
                  upload_data, upload_data_size ? *upload_data_size : 0);
        }
    }
    
    // 路由请求
    if (strcmp(url, "/api/hello") == 0 && strcmp(method, "GET") == 0) {
        status_code = handle_hello_request(&response_data);
    }
    else if (strcmp(url, "/api/login") == 0 && strcmp(method, "POST") == 0) {
        if (check_content_type(connection, &response_data, &status_code)) {
            handle_login_request(con_info, &response_data, &status_code);
        }
    }
    else {
        response_data = "{ \"error\": \"Not Found\" }";
        status_code = MHD_HTTP_NOT_FOUND;
    }
    
    // 创建并发送响应
    int is_dynamic = (strcmp(url, "/api/hello") == 0 && strcmp(method, "GET") == 0);
    struct MHD_Response *response = MHD_create_response_from_buffer(
        strlen(response_data), 
        (void*)response_data, 
        is_dynamic ? MHD_RESPMEM_MUST_FREE : MHD_RESPMEM_PERSISTENT);
    
    MHD_add_response_header(response, "Content-Type", "application/json");
    int ret = MHD_queue_response(connection, status_code, response);
    MHD_destroy_response(response);
    
    // 清理连接信息
    if (*con_cls) {
        struct connection_info *con_info = *con_cls;
        if (con_info->buffer) {
            free(con_info->buffer);
        }
        free(con_info);
        *con_cls = NULL;
    }
    
    return ret;
}

int main() {
    struct MHD_Daemon *daemon;
    
    daemon = MHD_start_daemon(
        MHD_USE_INTERNAL_POLLING_THREAD,
        PORT, NULL, NULL,
        &handle_request, NULL,
        MHD_OPTION_END);
    
    if (daemon == NULL) {
        fprintf(stderr, "Failed to start web server\n");
        return 1;
    }
    
    printf("C REST API server running on port %d\n", PORT);
    printf("Press Enter to stop server...\n");
    getchar();
    
    MHD_stop_daemon(daemon);
    return 0;
}